package com.itheima.aspect;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;

import cn.hutool.json.JSONUtil;
import com.google.gson.Gson;
import com.itheima.UserHolder;
import com.itheima.anno.LogAnno;
import com.itheima.exception.BusinessException;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {


    @Autowired
    private OperateLogMapper logMapper;

    // 切点表达式
    @Pointcut("@annotation(com.itheima.anno.LogAnno)")
    public void pt(){}


    @Around("pt()")
    public Object log(ProceedingJoinPoint pjp){

        long start = System.currentTimeMillis();

        OperateLog operateLog = new OperateLog();
        String className = pjp.getTarget().getClass().getName();
        operateLog.setClassName(className); //类名

        MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
        Method method = methodSignature.getMethod();
        String methodName = method.getName();
        operateLog.setMethodName(methodName);//方法名
        LogAnno logAnno = method.getAnnotation(LogAnno.class);
        operateLog.setMethodDesc(logAnno.methodDesc());//方法描述
        operateLog.setMethodParams(Arrays.toString(pjp.getArgs()));//方法参数
        operateLog.setOperateUser(UserHolder.getUserId());//方法操作人
        operateLog.setOperateTime(LocalDateTime.now());//方法操作时间
        Object obj = null;
        // 执行原方法
        try {
             obj = pjp.proceed();
            operateLog.setReturnValue( JSONUtil.toJsonStr(obj));//方法返回值
        } catch (Throwable throwable) {
           throw new BusinessException(throwable.getMessage());
        }finally {
            long end = System.currentTimeMillis();
            operateLog.setCostTime(end-start); //耗时

            logMapper.insert(operateLog);
        }

        return obj;
    }



}
